// 单例模式确保一个类只有一个实例，并提供一个全局访问点
const Singleton = (function() {
  let instance;

  function createInstance() {
    // 在这里创建单例对象
    const object = new Object("我是单例对象");
    return object;
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

// 使用单例模式
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();

console.log(instance1 === instance2); // true，只有一个实例

// 2. 工厂模式（Factory Pattern）：
// javascript
// 工厂模式通过工厂方法创建对象，而无需指定具体的类
function Car(make, model) {
  this.make = make;
  this.model = model;
}

function CarFactory() {}

CarFactory.prototype.createCar = function(make, model) {
  return new Car(make, model);
};

// 使用工厂模式
const factory = new CarFactory();
const car1 = factory.createCar("Toyota", "Camry");
const car2 = factory.createCar("Honda", "Accord");

console.log(car1); // Car { make: 'Toyota', model: 'Camry' }
console.log(car2); // Car { make: 'Honda', model: 'Accord' }
// 3. 观察者模式（Observer Pattern）：
// javascript
// 观察者模式定义了对象之间的一对多依赖关系，当一个对象改变状态时，它的所有依赖者都会收到通知
function Subject() {
  this.observers = [];
}

Subject.prototype.addObserver = function(observer) {
  this.observers.push(observer);
};

Subject.prototype.removeObserver = function(observer) {
  const index = this.observers.indexOf(observer);
  if (index !== -1) {
    this.observers.splice(index, 1);
  }
};

Subject.prototype.notifyObservers = function() {
  this.observers.forEach(function(observer) {
    observer.update();
  });
};

function Observer(name) {
  this.name = name;
}

Observer.prototype.update = function() {
  console.log(this.name + " 收到了通知");
};

// 使用观察者模式
const subject = new Subject();
const observer1 = new Observer("观察者1");
const observer2 = new Observer("观察者2");

subject.addObserver(observer1);
subject.addObserver(observer2);

subject.notifyObservers();
// 输出：
// 观察者1 收到了通知
// 观察者2 收到了通知

// 4. 原型模式（Prototype Pattern）：
// javascript
// 原型模式通过克隆现有对象来创建新对象，而无需使用显式的构造函数
function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.clone = function() {
  return Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
};

// 使用原型模式
const person1 = new Person("Alice", 25);
const person2 = person1.clone();

console.log(person1); // Person { name: 'Alice', age: 25 }
console.log(person2); // Person { name: 'Alice', age: 25 }
// 5. 装饰者模式（Decorator Pattern）：
// javascript
// 装饰者模式动态地将责任添加到对象上，可以在不改变原始对象的情况下，将功能进行组合和扩展
function Coffee() {
  this.cost = function() {
    return 10;
  };
}

function CoffeeDecorator(coffee) {
  this.coffee = coffee;
}

CoffeeDecorator.prototype.cost = function() {
  return this.coffee.cost();
};

CoffeeDecorator.prototype.addTopping = function(toppingCost) {
  return this.coffee.cost() + toppingCost;
};

// 使用装饰者模式
const coffee = new Coffee();
const coffeeWithMilk = new CoffeeDecorator(coffee);

console.log(coffee.cost()); // 10
console.log(coffeeWithMilk.addTopping(5)); // 15